<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.6.0.min.js"></script>
    <script defer="defer">
      // globals
      var curveLayer, lineLayer, anchorLayer, quad, bezier
      
      function updateDottedLines() {
        var q = quad;
        var b = bezier;

        var quadLine = lineLayer.get('#quadLine')[0];
        var bezierLine = lineLayer.get('#bezierLine')[0];

        quadLine.setPoints([q.start.attrs.x, q.start.attrs.y, q.control.attrs.x, q.control.attrs.y, q.end.attrs.x, q.end.attrs.y]);

        bezierLine.setPoints([b.start.attrs.x, b.start.attrs.y, b.control1.attrs.x, b.control1.attrs.y, b.control2.attrs.x, b.control2.attrs.y, b.end.attrs.x, b.end.attrs.y]);
        lineLayer.draw();
      }
      function buildAnchor(x, y) {
        var anchor = new Kinetic.Circle({
          x: x,
          y: y,
          radius: 20,
          stroke: '#666',
          fill: '#ddd',
          strokeWidth: 2,
          draggable: true
        });

        // add hover styling
        anchor.on('mouseover', function() {
          document.body.style.cursor = 'pointer';
          this.setStrokeWidth(4);
          anchorLayer.draw();
        });
        anchor.on('mouseout', function() {
          document.body.style.cursor = 'default';
          this.setStrokeWidth(2);
          anchorLayer.draw();
          
        });

        anchor.on('dragend', function() {
          drawCurves();
          updateDottedLines();
        });

        anchorLayer.add(anchor);
        return anchor;
      }
      function drawCurves() {
        var canvas = curveLayer.getCanvas();
        var context = canvas.getContext();
        
        canvas.clear();

        // draw quad
        context.beginPath();
        context.moveTo(quad.start.attrs.x, quad.start.attrs.y);
        context.quadraticCurveTo(quad.control.attrs.x, quad.control.attrs.y, quad.end.attrs.x, quad.end.attrs.y);
        context.strokeStyle = 'red';
        context.lineWidth = 4;
        context.stroke();

        // draw bezier
        context.beginPath();
        context.moveTo(bezier.start.attrs.x, bezier.start.attrs.y);
        context.bezierCurveTo(bezier.control1.attrs.x, bezier.control1.attrs.y, bezier.control2.attrs.x, bezier.control2.attrs.y, bezier.end.attrs.x, bezier.end.attrs.y);
        context.strokeStyle = 'blue';
        context.lineWidth = 4;
        context.stroke();
      }

      window.onload = function() {
        var stage = new Kinetic.Stage({
          container: 'container',
          width: 1000,
          height: 500
        });

        
        anchorLayer = new Kinetic.Layer();
        lineLayer = new Kinetic.Layer;

        // curveLayer just contains a canvas which is drawn
        // onto with the existing canvas API
        curveLayer = new Kinetic.Layer();

        var quadLine = new Kinetic.Line({
          dashArray: [10, 10, 0, 10],
          strokeWidth: 3,
          stroke: 'black',
          lineCap: 'round',
          id: 'quadLine',
          opacity: 0.3,
          points: [0, 0]
        });

        var bezierLine = new Kinetic.Line({
          dashArray: [10, 10, 0, 10],
          strokeWidth: 3,
          stroke: 'black',
          lineCap: 'round',
          id: 'bezierLine',
          opacity: 0.3,
          points: [0, 0]
        });

        // add dotted line connectors
        lineLayer.add(quadLine);
        lineLayer.add(bezierLine);

        quad = {
          start: buildAnchor(60, 30),
          control: buildAnchor(240, 110),
          end: buildAnchor(80, 160)
        };

        bezier = {
          start: buildAnchor(280, 20),
          control1: buildAnchor(530, 40),
          control2: buildAnchor(480, 150),
          end: buildAnchor(300, 150)
        };

        // keep curves insync with the lines
        anchorLayer.on('beforeDraw', function() {
          drawCurves();
          updateDottedLines();
        });

    

        stage.add(curveLayer);
        stage.add(lineLayer);
        stage.add(anchorLayer);

        drawCurves();
        updateDottedLines();

      };

    </script>
  </head>
  <body onmousedown="return false;">
    <div id="container"></div>
  </body>
</html>